package com.fox.stock.sharding;

import com.google.common.collect.Range;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingValue;
import org.joda.time.DateTime;

import java.util.Collection;
import java.util.Date;
import java.util.Optional;
import java.util.stream.Collectors;

public class commonAlg4Tb implements PreciseShardingAlgorithm<Date>, RangeShardingAlgorithm<Date> {

    /**
     * 精准查询分表
     * @param dtNames 分表数据源集合
     * @param preciseShardingValue 分片键数据封装类
     * @return 过滤后的数据源
     */
    @Override
    public String doSharding(Collection<String> dtNames, PreciseShardingValue<Date> preciseShardingValue) {
        Date value = preciseShardingValue.getValue();
        String date = new DateTime(value).toString("yyyyMM");
        Optional<String> first = dtNames.stream().filter(dtName -> dtName.endsWith(date)).findFirst();
        if (first.isPresent()) {
            return first.get();
        }
        return "";
    }


    /**
     * 范围查询分表
     * @param dtNames 分表数据源集合
     * @param rangeShardingValue 分片键数据封装类
     * @return 过滤后的数据源
     */
    @Override
    public Collection<String> doSharding(Collection<String> dtNames, RangeShardingValue<Date> rangeShardingValue) {
        Range<Date> valueRange = rangeShardingValue.getValueRange();
        //判断下线
        if (valueRange.hasLowerBound()) {
            // 获取年份
            Date date = valueRange.lowerEndpoint();
            int startYear = Integer.parseInt(new DateTime(date).toString("yyyyMM"));
            dtNames = dtNames.stream().filter(dtName->Integer.parseInt(dtName.substring(dtName.lastIndexOf('_')+1))>=startYear).collect(Collectors.toList());
        }

        //判断上线
        if (valueRange.hasUpperBound()) {
            // 获取年份
            Date date = valueRange.upperEndpoint();
            int endYear = Integer.parseInt(new DateTime(date).toString("yyyyMM"));
            dtNames = dtNames.stream().filter(dtName->Integer.parseInt(dtName.substring(dtName.lastIndexOf('_')+1))<=endYear).collect(Collectors.toList());
        }
        return dtNames;
    }
}
